<template>
  <div class="preview-wrap">
    <div ref="previewRef" class="preview-wrap-scale" :style="previewStyle">
      <transition-group appear name="bounce">
        <template v-for="(item, index) in designCache.components" >
          <!-- 组合 -->
          <template v-if="item.isGroup" >
            <view-group v-if="!item.isHidden" :key="item.id" :item="item" :index="index" :length="designCache.components.length"/>
          </template>

          <template v-else>
            <div v-if="!item.isHidden"
                 :key="item.id"
                 class="preview-wrap-block"
                 :style="{width:Math.round(item.cptWidth)+'px',
                  height:Math.round(item.cptHeight)+'px',
                  top:Math.round(item.cptY)+'px',
                  left:Math.round(item.cptX)+'px',
                  transform: 'rotate('+item.cptRotate+'deg)',
                  zIndex: designCache.components.length-(index+1)}">

              <component :is="item.cptKey"
                         :ref="item.id"
                         :width="Math.round(item.cptWidth)"
                         :height="Math.round(item.cptHeight)"
                         @reload="loadCacheData"
                         :option="item.cptOption" @clickHandler="clickHandler"/>
            </div>
          </template>

        </template>

      </transition-group>
    </div>
  </div>
</template>

<script>
import {authViewCodeApi} from "@/api/DesignerApi";
import {fileUrl} from "/env";
import {getReportdashboardDetailId} from "@/api/dashboard"

import viewGroup from './components/viewGroup'

export default {
  name: "preview_index",
  components: {
    viewGroup
  },
  data(){
    return{
      fileUrl:fileUrl,
      designCache:{},
      conHeight: 0,
      containerScale:1,
      authCodeDialogVisible:false,
      viewCode:''
    }
  },
  mounted() {
    const that = this;
    that.loadCacheData();
    window.onresize = () => {
      return (() => {
        that.loadSize()
      })();
    };
  },
  methods: {
    initConstants() {
      const map = {}
      const query = window.location.href.split('?')[1]
      if(query) {
        const arr = query.split('&')
        arr.forEach(str => {
          const kv = str.split('=')
          map[kv[0]] = kv[1]
        })
      }
      return map
    },
    loadCacheData(){
      const path = this.$route.path;
      const that = this;
      const id = this.$route.query.id;
      if (path === '/preview'){
        let designCache = JSON.parse(localStorage.getItem('designCache'));
        this.loadDesign(designCache, false);
      }else if(path === '/view'){
        if (!id) {
          this.$message.error('id错');
          return;
        }
        const viewCode = localStorage.getItem('code'+id) || '';//如果已经输入过访问码就带着访问码一起请求
        getReportdashboardDetailId(id, {viewCode: viewCode}).then(res => {
          if (res === 'NEED_AUTH') {
            // that.authCodeDialogVisible = true;
            this.showDialog()
          }else{
            that.loadDesign(res, true);
          }
        })
      }
    },
    showDialog() {
      this.$prompt('请输入访问码', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        showClose: false,
        showCancelButton: false
      }).then(rs => {
        if(rs.value === null || rs.value === '' || typeof rs.value === 'undefined') {
          this.showDialog()
        } else {
          const id = this.$route.query.id
          localStorage.setItem('code' + id, rs.value)
          this.loadCacheData()
        }
      })
    },
    loadDesign(design, needParse){
      if(needParse) {
        if(design.constants) {
          design.constants = JSON.parse(design.constants)
        }
        design.components.forEach(comp => {
          comp.cptOption = JSON.parse(comp.cptOption)
          comp.status = JSON.parse(comp.status)
          comp.isHidden = comp.isHidden || false
          if(comp.isGroup && comp.groupList) {
            comp.groupList = JSON.parse(comp.groupList)
          }
        })
      } else {
        design.components.forEach(comp => {
          comp.isHidden = comp.isHidden || false
        })
      }

      const urlParam = this.initConstants()
      design.constants = Object.assign({}, design.constants, urlParam)

      document.title = design.title;
      this.designCache = design;
      this.loadSize();
    },
    authCode(){
      if (!this.viewCode){
        this.$message.error('请输入访问码');
        return;
      }
      const id = this.$route.query.id;
      authViewCodeApi({id: id, viewCode:this.viewCode}).then(res => {
        this.authCodeDialogVisible = false;
        localStorage.setItem('code'+id, res.data.viewCode);//缓存访问码避免二次刷新需要再次输入
        this.loadDesign(res.data,true)
      })
    },
    loadSize(){
      if(this.designCache.screenAdapter === 'auto') {
        this.screenAuto()
      } else if(this.designCache.screenAdapter === 'stretch') {
        this.screenStretch()
      }
    },
    screenAuto() {
      // 等缩放，会留白
      const windowWidth = document.documentElement.clientWidth
      const windowHeight = document.documentElement.clientHeight
      const el = this.$refs.previewRef

      let per = windowWidth / this.designCache.scaleX
      let pery = per

      if(this.designCache.scaleY * per > windowHeight) {
        pery = windowHeight / this.designCache.scaleY
        per = pery
      }
      el.style.transform = 'scaleX(' + per + ') scaleY(' + pery + ') translateX(-50%) translateY(-50%)'
    },
    screenStretch() {
      // 拉伸
      const windowWidth = document.documentElement.clientWidth
      const windowHeight = document.documentElement.clientHeight
      const el = this.$refs.previewRef
      let per = windowWidth / this.designCache.scaleX
      const pery = windowHeight / this.designCache.scaleY
      el.style.transform = 'scaleX(' + per + ') scaleY(' + pery + ') translateX(-50%) translateY(-50%)'
    },
    clickHandler(interaction, key='default', defaultValue) {
      console.info('interaction:', interaction)
      if(!interaction.active) {
        return
      }
      const target = interaction.objMap[key]
      switch (interaction.intType) {
        case 'display':
          if(target.show.length > 0) {
            target.show.forEach(id => {
              const index = this.designCache.components.findIndex(o => o.id === id)
              if(index !== -1) {
                this.designCache.components[index].isHidden = false
              }
            })
          }
          if(target.hidden.length > 0) {
            target.hidden.forEach(id => {
              const index = this.designCache.components.findIndex(o => o.id === id)
              if(index !== -1) {
                this.designCache.components[index].isHidden = true
              }
            })
          }
          break;
        case 'api':
          this.updateApi(target, defaultValue)
          break;
        case 'drill':break;
        case 'redirect':
          console.info(target.redirectUrl)
          if(!target.redirectUrl) {
            return
          }
          if(target.redirectType === '_self') {
            window.location.href = target.redirectUrl
          } else {
            window.open(target.redirectUrl)
          }
          break;
      }
    },
    updateApi(target, defaultValue) {
      const {paramName, paramType, paramValue, changeDataset = []} = target
      if(!changeDataset || changeDataset.length === 0) {
        console.warn('没有可更新的对象组件')
        return
      }

      let value = paramValue
      if(paramType === 'auto') {
        value = defaultValue
      } else if(paramType === 'const') {
        value = this.designCache.constants[paramValue]
      }
      changeDataset.forEach(id => {
        if(this.$refs[id] && this.$refs[id][0] && this.$refs[id][0].refreshCptData) {
          this.$refs[id][0].refreshCptData([{paramName, sampleItem: value}])
        }
      })
    }
  },
  computed: {
    previewStyle() {
      const style = {
        width: `${this.designCache.scaleX}px`,
        height: `${this.designCache.scaleY}px`,
        background: this.designCache.bgColor,
        backgroundImage: this.designCache.bgImg ? `url(${this.designCache.bgImg})` : 'none',
        backgroundSize: '100% 100%'
      }

      return style
    }
  }
}
</script>

<style lang="less" scoped>
.preview-wrap {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #000;

  &-scale {
    position: relative;
    left: 50%;
    top: 50%;
    transform-origin: 0 0;
    transform: translate(-50%, -50%);
  }

  &-block {
    position: absolute;
  }
}
.bounce-enter-active{
  transition: all 1s;
  /*animation: bounce-in 1s;*/
}
.bounce-enter{
  opacity: 0;
  transform: scale(.5);
}
@keyframes bounce-in {
  0% {
    transform: scale(0);
  }
  25% {
    transform: scale(0.5);
  }
  50% {
    transform: scale(1);
  }
  75% {
    transform: scale(1.5);
  }
  100% {
    transform: scale(1);
  }
}
</style>
